import { deepMerge } from '../utils/index.js';

/**
 * 配置管理器类
 * 负责管理、合并和访问框架配置
 */
class ConfigManager {
  constructor(defaultConfig = {}) {
    this.config = { ...defaultConfig };
  }

  /**
   * 合并配置
   * @param {Object} newConfig - 新的配置对象
   * @returns {ConfigManager} 当前实例，支持链式调用
   */
  merge(newConfig) {
    deepMerge(this.config, newConfig);
    return this;
  }

  /**
   * 获取配置值
   * @param {string} key - 配置键，可以使用点表示法访问嵌套配置
   * @param {*} defaultValue - 默认值，当配置不存在时返回
   * @returns {*} 配置值或默认值
   */
  get(key, defaultValue = undefined) {
    if (!key) {
      return this.config;
    }

    const keys = key.split('.');
    let value = this.config;

    for (const k of keys) {
      if (value === null || typeof value !== 'object' || !(k in value)) {
        return defaultValue;
      }
      value = value[k];
    }

    return value;
  }

  /**
   * 设置配置值
   * @param {string} key - 配置键，可以使用点表示法设置嵌套配置
   * @param {*} value - 配置值
   * @returns {ConfigManager} 当前实例，支持链式调用
   */
  set(key, value) {
    if (!key) {
      throw new Error('Config key cannot be empty');
    }

    const keys = key.split('.');
    let config = this.config;

    // 遍历键，创建不存在的嵌套对象
    for (let i = 0; i < keys.length - 1; i++) {
      const k = keys[i];
      if (!config[k] || typeof config[k] !== 'object') {
        config[k] = {};
      }
      config = config[k];
    }

    // 设置最终值
    config[keys[keys.length - 1]] = value;
    return this;
  }

  /**
   * 检查配置是否存在
   * @param {string} key - 配置键
   * @returns {boolean} 是否存在
   */
  has(key) {
    return this.get(key, undefined) !== undefined;
  }

  /**
   * 移除配置
   * @param {string} key - 配置键
   * @returns {ConfigManager} 当前实例，支持链式调用
   */
  remove(key) {
    if (!key) {
      throw new Error('Config key cannot be empty');
    }

    const keys = key.split('.');
    let config = this.config;
    let parent;
    let lastKey;

    // 遍历键，找到要移除的配置的父对象
    for (let i = 0; i < keys.length; i++) {
      lastKey = keys[i];
      if (!config || typeof config !== 'object' || !(lastKey in config)) {
        return this; // 键不存在，直接返回
      }
      
      if (i === keys.length - 1) {
        delete config[lastKey];
      } else {
        parent = config;
        config = config[lastKey];
      }
    }

    return this;
  }

  /**
   * 获取完整配置
   * @returns {Object} 完整配置对象
   */
  getAll() {
    return { ...this.config };
  }

  /**
   * 重置配置
   * @param {Object} newConfig - 可选的新配置对象
   * @returns {ConfigManager} 当前实例，支持链式调用
   */
  reset(newConfig = {}) {
    this.config = { ...newConfig };
    return this;
  }
}

export default ConfigManager;